package orm

import (
	"appService/src/global/paginate"
	"errors"
	"github.com/gogf/gf/frame/g"
	"xorm.io/xorm"
)

//Transaction 事务处理
//【actionName 操作名称，如：保存，修改】
//【logicHandle 业务逻辑】
//【errHandle 事务提交失败回调】
func Transaction(actionName string, logicHandle func(db *xorm.Session) error, errHandle ...func()) error {
	db := Db.NewSession()
	defer func() {
		_ = db.Close()
	}()
	err := db.Begin()
	if err != nil {
		g.Log().Errorf("开启事务失败，错误：%v", err)
		return errors.New(actionName + "失败")
	}
	err = logicHandle(db)
	if err == nil {
		err = db.Commit()
		if err == nil {
			return nil
		} else {
			_ = db.Rollback()
			g.Log().Errorf("提交事务失败，错误：%v", err)
			if len(errHandle) > 0 {
				errHandle[0]()
			}
			return errors.New(actionName + "失败")
		}
	} else {
		_ = db.Rollback()
		g.Log().Errorf("【Transaction】函数【handle】处理失败，错误：%v", err)
		if len(errHandle) > 0 {
			errHandle[0]()
		}
		return errors.New(actionName + "失败")
	}
}

//Insert 插入数据
func Insert(db *xorm.Session, model interface{}) error {
	_, err := db.Insert(model)
	if err == nil {
		return nil
	} else {
		return err
	}
}

//Delete 删除数据
func Delete(db *xorm.Session, model interface{}, where func(db *xorm.Session)) error {
	where(db)
	if _, err := db.Delete(model); err == nil {
		return nil
	} else {
		return err
	}
}

//Update 更新数据
func Update(db *xorm.Session, model interface{}, where func(db *xorm.Session)) error {
	where(db)
	if _, err := db.Update(model); err == nil {
		return nil
	} else {
		return err
	}
}

//Find 查询数据列表
//【db 数据库连接上下文】
//【table 要查询的表名称或对象指针】
//【list 用于存储查询数据的对象数组指针】
//【where 查询条件回调函数】
func Find(db *xorm.Session, table interface{}, list interface{}, where func(db *xorm.Session)) error {
	db.Table(table)
	where(db)
	err := db.Find(list)
	if err == nil {
		return nil
	} else {
		return err
	}
}

//FindPaginate 查询数据列表（分页）
//【db 数据库连接上下文】
//【table 要查询的表名称或对象指针】
//【pageData 用于存储查询分页数据的分页数据结构体对象指针】
//【countWhere 记录数查询条件回调函数】
//【findWhere 查询条件回调函数，返回用于存储查询数据的对象数组指针】
func FindPaginate(db *xorm.Session, table interface{}, pageData *paginate.PaginateData, countWhere func(db *xorm.Session), findWhere func(db *xorm.Session) interface{}) error {
	db.Table(table)
	countWhere(db)
	rows, err := db.Count()
	if err != nil {
		return err
	}
	db.Table(table)
	countWhere(db)
	pageData.Paginate.CalcPaginate(rows)
	db.Limit(pageData.Paginate.Limit, pageData.Paginate.Start)
	list := findWhere(db)
	err = db.Find(list)
	if err == nil {
		pageData.Data = list
		return nil
	} else {
		return err
	}
}

//FindPaginateEx 查询数据列表（分页）
//【db 数据库连接上下文】
//【table 要查询的表名称或对象指针】
//【list 用于存储查询数据的对象数组指针】
//【pageData 用于存储查询分页数据的分页数据结构体对象指针】
//【countWhere 记录数查询条件回调函数】
//【findWhere 查询条件回调函数】
func FindPaginateEx(db *xorm.Session, table interface{}, list interface{}, pageData *paginate.PaginateData, countWhere func(db *xorm.Session), findWhere func(db *xorm.Session)) error {
	db.Table(table)
	countWhere(db)
	rows, err := db.Count()
	if err != nil {
		return err
	}
	db.Table(table)
	countWhere(db)
	pageData.Paginate.CalcPaginate(rows)
	db.Limit(pageData.Paginate.Limit, pageData.Paginate.Start)
	findWhere(db)
	err = db.Find(list)
	if err == nil {
		pageData.Data = list
		return nil
	} else {
		return err
	}
}
